package com.zyc.provider.impl;

import com.zyc.enums.RpcErrorMessageEnum;
import com.zyc.exception.RpcException;
import com.zyc.provider.ServiceProvider;
import com.zyc.registry.ServiceRegistry;
import com.zyc.registry.zk.ZKServiceRegistryImpl;
import com.zyc.remoting.transport.socket.SocketConstant;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用zookeeper做注册中心
 * @author zyc
 * @create 2022--05--16 16:58
 */
@Slf4j
public class ZKServiceProviderImpl implements ServiceProvider {
    private final Map<String, Object> serviceMap;
    private final Set<String> registeredService;
    private final ServiceRegistry serviceRegistry;

    public ZKServiceProviderImpl() {
        serviceMap = new ConcurrentHashMap<>();
        registeredService = ConcurrentHashMap.newKeySet();
        //TODO 动态加载扩展程序
        serviceRegistry = new ZKServiceRegistryImpl();
    }

    @Override
    public void addService(Object rpcService) {
        String rpcServiceName = rpcService.getClass().getInterfaces()[0].getCanonicalName();
        if (registeredService.contains(rpcServiceName)) {
            return;
        }
        registeredService.add(rpcServiceName);
        serviceMap.put(rpcServiceName, rpcService);
        log.info("添加服务:{}, 其接口为：{}", rpcServiceName, rpcService.getClass().getInterfaces());
    }

    @Override
    public Object getService(String rpcServiceName) throws RpcException {
        Object service = serviceMap.get(rpcServiceName);
        if (service == null) {
            throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_FOUND);
        }
        return service;
    }

    @Override
    public void publishService(Object rpcService) {
        String rpcServiceName = rpcService.getClass().getInterfaces()[0].getCanonicalName();

        try {
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            addService(rpcService);
            serviceRegistry.registerService(rpcServiceName, new InetSocketAddress(hostAddress, SocketConstant.servicePort));
        } catch (UnknownHostException e) {
            log.error("获取本机地址时候出现异常", e);
        }
    }

    @Override
    public void publishService(Object rpcService, int port) {
        String rpcServiceName = rpcService.getClass().getInterfaces()[0].getCanonicalName();

        try {
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            addService(rpcService);
            serviceRegistry.registerService(rpcServiceName, new InetSocketAddress(hostAddress, port));
        } catch (UnknownHostException e) {
            log.error("获取本机地址时候出现异常", e);
        }
    }
}
